package com.user.test.viewModel

import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.user.test.model.database.SearchResult
import com.user.test.model.retrofit.SearchResultApi
import com.user.test.model.retrofit.SearchResultItem
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import java.lang.NullPointerException
import java.util.concurrent.Executors


class RetrofitViewModel(application: Application) : AndroidViewModel(application) {

    private val linkLiveData : MutableLiveData<String> by lazy {MutableLiveData<String>()}
    private val responseLiveData : MutableLiveData<MutableList<SearchResult>> by lazy { MutableLiveData<MutableList<SearchResult>>() }
    private val errorLiveData : MutableLiveData<String> by lazy {MutableLiveData<String>()}
    private val compositeDisposable = CompositeDisposable()

    private val pool = Executors.newFixedThreadPool(2)
    private var startPage = -1
    private var processState = 0

    override fun onCleared() {
        compositeDisposable.dispose()
        super.onCleared()
    }

    fun getLink():MutableLiveData<String>{
        return linkLiveData
    }

    fun getResponse():MutableLiveData<MutableList<SearchResult>>{
        return responseLiveData
    }

    fun getError():MutableLiveData<String>{
        return errorLiveData
    }


    fun fetchSearchResultList(searchResultApi: SearchResultApi?, request:String){
        searchResultApi?.let{
                processState = 1
            compositeDisposable.add(dataSource(searchResultApi, request))
            compositeDisposable.add(dataSource(searchResultApi, request))
            compositeDisposable.add(dataSource(searchResultApi, request))
            compositeDisposable.add(dataSource(searchResultApi, request))
        }
    }

    private fun dataSource(searchResultApi: SearchResultApi, request:String): Disposable {
        return searchResultApi.getSearchResultList(request, getStartPage())
            //.zipWith(searchResultApi.getSearchResultList(request, getStartPage())) { t1, t2 -> t1.items.addAll(t2.items); t1 }
            .flatMap {Single.just(adaptResponseToDatabase(it.items, Thread.currentThread().name.split("-")[3].toInt())) }
            .map{ println("!!Real Thread ${Thread.currentThread().name}"); it}
            .subscribeOn(Schedulers.from(pool))
            .doOnDispose { Log.e("DIspose!!", "Dispose ${Thread.currentThread().name}") }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                responseLiveData.value = it

                       },{
                when{
                    it is HttpException && it.code() == 429 -> errorLiveData.value = "incorrect api"
                    (it is NullPointerException && Thread.currentThread().name.split("-")[3].toInt() == 1) -> {
                    errorLiveData.value = "Not result"
                    compositeDisposable.dispose()
                }
                    it is NullPointerException -> errorLiveData.value = "Not result"
                }
                Log.e("!!ViewModel response from ${Thread.currentThread().name} thread", "$it") })
    }


    private fun getStartPage(): Int {
        startPage++
        println("\n*****************************\nStartPage = $startPage\n*****************************")
        if (startPage == 4){
            startPage = 0
        }else if(startPage == 0){
            return startPage
        }
        return startPage * 10
    }

    private fun adaptResponseToDatabase(array : MutableList<SearchResultItem>, thread: Int):MutableList<SearchResult>{
        val searchResultList = mutableListOf<SearchResult>()
        for(i in 0..array.size-1){
            searchResultList.add(i, SearchResult(array[i].title, thread, array[i].link))
        }
        return searchResultList
    }
}